package AM;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.ArrayList;

public class CatchHeroin_CopyCilent extends Thread {

	CatchHeroin_Server server;
	Socket s;
	ObjectInputStream in;
	ObjectOutputStream out;

	private String nickname; // 닉네임
	private String score; // 스코어
	private String whether_good_wrong; // 정답여부
	private boolean login_yn = false; // 로그인여부

	private boolean isCheckTurn = false; // 턴 여부

	ArrayList<UserInfo> uInfoList;

	public String getNickname() {
		return nickname;
	}

	public void setNickname(String nickname) {
		this.nickname = nickname;
	}

	public String getScore() {
		return score;
	}

	public void setScore(String score) {
		this.score = score;
	}

	public String getWhether_good_wrong() {
		return whether_good_wrong;
	}

	public void setWhether_good_wrong(String whether_good_wrong) {
		this.whether_good_wrong = whether_good_wrong;
	}

	public CatchHeroin_CopyCilent(Socket s, CatchHeroin_Server server) {

		this.s = s;
		this.server = server;
		try {
			in = new ObjectInputStream(s.getInputStream());
			out = new ObjectOutputStream(s.getOutputStream());
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}

	}

	public boolean isLogin_yn() {
		return login_yn;
	}

	public void setLogin_yn(boolean login_yn) {
		this.login_yn = login_yn;
	}

	@Override
	public void run() {

		/**
		 * cmd = 0일때 nickName들을 얻어서 중복 여부를 비교하여 true/false를 해당 클라이언트에게만 전송한다. --
		 * server.getNames();
		 * 
		 * cmd = 100일때
		 * 
		 */
		copy_client_thread: while (true) {
			try {
				Object obj = in.readObject();
				Protocol p = (Protocol) obj;
				int nextIndex = 0;
				
				switch (p.getCmd()) {
				case Protocol.LOG_IN:

//					System.out.println("cc : LOG_IN");

					String[] temp_client_nickname_list = server
							.getnickNameList();
					String temp_nickname = p.getMsg();

					boolean duplicated = true;
					if (temp_client_nickname_list.length > 1) {
						// 접속된 client nickname리스트가 0보다 크면.. 즉, 접속한 클라이언트가 1명
						// 이상이면 중복 체크한다.

						for (String str : temp_client_nickname_list) {
							if (temp_nickname.equals(str)) { // 종복된 닉네임이 있을경우.
								p.setCmd(Protocol.LOG_IN);
								p.setMsg("duplicated_nickname");
								out.writeObject(p);
								duplicated = false;
								break;
							}
						}
					}

					if (duplicated) {
						// 중복된 닉네임이 아니면 LOG_IN커맨드를 다시 날려 로그인을 허가하자.
						nickname = p.getMsg();
						p.setCmd(Protocol.LOG_IN);
						p.setMsg("");
						p.setClientLength(server.getClientSize()); // client에 전체
																	// 사용자 수를
																	// 보내준다.

						out.writeObject(p);
					}

					break;

				case Protocol.CLIENT_LOG_IN:

//					System.out.println("cc : CLIENT_LOG_IN");
					login_yn = true;

					// 내정보를 담는다.

					UserInfo uInfo = new UserInfo();
					uInfo.setNickName(nickname);
					uInfo.setScore(0);
					uInfo.setWhether_good_wrong("-");

					if (server.getClientSize() == 1) {
						uInfo.setTurn(true); // 처음 로그인하면 턴을 갖는다.
						isCheckTurn = true;
						server.turnIndex = 0;
					} else {
						uInfo.setTurn(false);
					}

					server.addUserInfo(uInfo);

					// p = new Protocol();
					p.setCmd(Protocol.CLIENT_LOG_IN);

					uInfoList = new ArrayList<UserInfo>();
					for (UserInfo u : server.getUserInfoList()) {
						uInfoList.add(u);
					}
					p.setUser_list(uInfoList);

					server.sendMessage(p);

					break;
				case Protocol.SEND_MSG:
					
					uInfoList = new ArrayList<UserInfo>();
					
				
					
					for (int i = 0; i < server.getUserInfoList().size(); i++) {

						UserInfo u = server.getUserInfoList().get(i);
						
						UserInfo u_temp = new UserInfo();
						u_temp.setNickName(u.getNickName());
						
						if(nickname.equals(u.getNickName())){
							u_temp.setScore(Integer.parseInt(p.getScore()));
							u_temp.setWhether_good_wrong(p.getMsg());
							u.setScore(Integer.parseInt(p.getScore()));
							u.setWhether_good_wrong(p.getMsg());
						}else{
							u_temp.setScore(u.getScore());
							u_temp.setWhether_good_wrong(u.getWhether_good_wrong());
						}
						
						if (i == server.turnIndex) {

							u_temp.setTurn(true);

						}else{
							u_temp.setTurn(false);
						}

						uInfoList.add(u_temp);
						
					}
					p.setUser_list(uInfoList);
					p.setCmd(Protocol.SEND_MSG);

					server.sendMessage(p);

					break;
				case Protocol.DRAWING_CANVAS:
					// 서버에서 전달된 p는 DRAWING_CANVAS 이므로 따로 가공 없이 바로 전송

					server.sendMessage(p);
					break;
				case Protocol.CLEAR_CANVAS:
					// 서버에서 전달된 p는 CLEAR_CANVAS 이므로 따로 가공 없이 바로 전송

					server.sendMessage(p);

					break;
				case Protocol.GAME_START:
					server.sendMessage(p);
					break;

				case Protocol.GAME_END:

//					System.out.println("GAME_END....");

					uInfoList = new ArrayList<UserInfo>();
					
					nextIndex = server.turnIndex + 1;
					
					if (server.turnIndex == server.getClientSize()-1){
						System.out.println();
						nextIndex = 0;
					}
					
					server.turnIndex = nextIndex;
					
					for (int i = 0; i < server.getUserInfoList().size(); i++) {

						UserInfo u = server.getUserInfoList().get(i);
						
						UserInfo u_temp = new UserInfo();
						u_temp.setNickName(u.getNickName());
						u_temp.setScore(u.getScore());
						u_temp.setWhether_good_wrong(u.getWhether_good_wrong());
						u_temp.setTurn(false);

						if (i == nextIndex) {

							u_temp.setTurn(true);

						}

						uInfoList.add(u_temp);
					}
					p.setUser_list(uInfoList);
					p.setCmd(Protocol.CLIENT_LOG_IN);

					server.sendMessage(p);
					break;
				case Protocol.EXIT_CLIENT:
					
					server.delCilent(this);		// 서버에 내 copyClient 삭제

					for (UserInfo u : server.user_info_list) {
						if (nickname.equals(u.getNickName())) {
							
							server.user_info_list.remove(u);	//내 정보(UserInfo) 삭제
							
							if (u.isTurn()) { // 나가는 사용자가 턴이면 턴변경 작업
								uInfoList = new ArrayList<UserInfo>();
								
								nextIndex = server.turnIndex + 1;
								
								if (server.turnIndex == server.getClientSize()-1){
									System.out.println();
									nextIndex = 0;
								}
								
								server.turnIndex = nextIndex;
								
								for (int i = 0; i < server.getUserInfoList().size(); i++) {

									UserInfo tu = server.getUserInfoList().get(i);
									
									UserInfo u_temp = new UserInfo();
									u_temp.setNickName(tu.getNickName());
									u_temp.setScore(tu.getScore());
									u_temp.setWhether_good_wrong(tu.getWhether_good_wrong());
									u_temp.setTurn(false);

									if (i == nextIndex) {

										u_temp.setTurn(true);

									}

									uInfoList.add(u_temp);
								}
								p.setUser_list(uInfoList);
								p.setCmd(Protocol.CLIENT_LOG_IN);

								server.sendMessage(p);
							}
							
							break;
						}
					}

					p.setCmd(Protocol.EXIT_CLIENT);
					out.writeObject(p);
					break copy_client_thread;

				}
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
		}
		closed();
	}

	private void closed() {
		try {
			if (in != null)
				in.close();
			if (out != null)
				out.close();
			if (s != null)
				s.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
